package smsapi.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import smsapi.ApiException;
import smsapi.util.Constants;
import smsapi.util.Md5Util;
import smsapi.util.Signer;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.TreeMap;

@Component
public class ApiBase {

    @Autowired
    protected RestTemplate restTemplate;
    @Autowired
    protected Signer singer;

    @Value("${smsapi.basepath:}")
    String basepath;
    @Value("${smsapi.companyno:}")
    String companyNo;
    @Value("${smsapi.loginname:}")
    String loginName;
    @Value("${smsapi.privatekeypem:}")
    String privatekeypem;
    /**
     * Escape the given string to be used as URL query value.
     *
     * @param str String to be escaped
     * @return Escaped string
     */
    protected String escapeString(String str) {
        try {
            return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            return str;
        }
    }

    // SignData(privatekey,header+data,Md5)
    protected String generateSignature(String timestamp, String nonce) {
        Map<String, String> sortedMap = new TreeMap<>();
        sortedMap.put("timestamp", timestamp);
        sortedMap.put("nonce", nonce);
        sortedMap.put("companyNo", companyNo);
        sortedMap.put("loginName", loginName);
        String content = Signer.getSignCheckContent(sortedMap);
        String signature = singer.sign(content,privatekeypem);
        return signature;
    }
    protected HttpHeaders getHttpHeaders(Object request, String timestamp, String nonce, String token) throws ApiException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("timestamp", timestamp);
        headers.add("nonce", nonce);
        headers.add("companyNo", companyNo);
        headers.add("token", token);
        String signature = null;
        try {
            signature = generateSignature(timestamp, nonce, token,request);
        } catch (JsonProcessingException e) {
            throw  new ApiException(e);
        }
        headers.add("signature", signature);
        headers.add("Accept", "application/json");
        headers.add("Content-Type", "application/json");
        return headers;
    }
    protected HttpHeaders getHttpHeaders(String timestamp, String nonce, String token) throws ApiException {
        return getHttpHeaders(null, timestamp, nonce, token);
    }

    private String generateSignature(String timestamp, String nonce,String token) throws JsonProcessingException {
        return generateSignature(timestamp, nonce, token,null);
    }
    private String generateSignature(String timestamp, String nonce,String token,Object request) throws JsonProcessingException {
        Map<String, String> sortedMap = new TreeMap<>();
        sortedMap.put("timestamp", timestamp);
        sortedMap.put("nonce", nonce);
        sortedMap.put("companyNo", companyNo);
        sortedMap.put("token", token);
        ObjectMapper mapper = new ObjectMapper();
        if(request!=null){
            sortedMap.put("data", mapper.writeValueAsString(request));
        }
        String content = Signer.getSignCheckContent(sortedMap);
        String signature = Md5Util.md5(content, "utf8");
        return signature;
    }
}
